package pack.help.realRobot.uC;

import pack.help.realRobot.SignalChange;
import pack.help.realRobot.uC.UC.WhichSide;
import pack.model.RealLifeProperties;

public class TimerCnt {
	private int stepTarget;
	private int speedTarget;
	
	private int currentSteps;
	private int currentSpeed;
	
	private int nextSpeed;
	
	private UC uC;
	private WhichSide which;
	
	static final int maxValue = 255;
	
	
	public TimerCnt(UC uC, WhichSide which){
		
		this.uC = uC;
		this.which = which;
		
		currentSpeed = maxValue;
	}
	
	public void start(int steps, int speed){
		this.stepTarget = steps;
		this.speedTarget = speed;
		
		currentSteps = 0;
		
		nextSpeed = maxValue;
		
		new Ticker(this).start();
	}
	
	public void setNextSpeed(int nextSpeed){
		this.nextSpeed = nextSpeed;
	}
	
	public void end(){
		uC.timerEnded(which);
	}
	
	public void stop(){
		// TO DO stop timer from outside
	}
	
	public void tick(){	
		uC.invertPort(which);
		if (uC.getPort(which).getChange() == SignalChange.DESCEND){
			this.currentSteps++;
			
			if (currentSpeed > speedTarget){
				currentSpeed--;
			} else if (currentSpeed < speedTarget){
				currentSpeed ++;
			}
			
			if ( nextSpeed > speedTarget ){
				if (currentSteps + nextSpeed - speedTarget > stepTarget){
					currentSpeed++;
				}
			} else {
				if (currentSteps + speedTarget - nextSpeed > stepTarget){
					currentSpeed--;
				}
			}
			
		}
	}
	
	private class Ticker extends Thread{

		TimerCnt timer;
		private final int secToNano = (int)Math.pow(10, 9);
		
		public Ticker(TimerCnt t){
			this.timer = t;
		}
		
		public void run() {
			long prev = System.nanoTime();
			while(timer.stepTarget <= timer.currentSteps){
				if (System.nanoTime()-prev >= (secToNano /RealLifeProperties.timerFrequency)*timer.currentSpeed){
					timer.currentSteps++;
					timer.tick();
					prev = System.nanoTime();
				}
			}
			timer.currentSteps = 0;
			timer.uC.timerEnded(which);
		}
		
		
	
	}
}
